/*
 * topological-hex, a program to compute combinatorial hexahedral meshes.
 *
 * Copyright (C) <2018> <Université catholique de Louvain (UCL), Belgique>
 *
 * List of the contributors to the development, description and complete
 * License: see LICENSE file.
 *
 * This program (topological-hex) is free software:
 * you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (see COPYING file).  If not,
 * see <http://www.gnu.org/licenses/>.
 */

#ifndef SHELLABLE_DFS_H_
#define SHELLABLE_DFS_H_

#include "solver.h"

typedef struct shellable_delta {
  uint8_t num_new_quads;
  uint8_t num_new_edges;
  uint8_t queue_offset_change;
  uint8_t num_new_vertices;
  uint8_t num_finished_vertices;

  vertex_index new_edges[16];
  quad_index quads[6];
  vertex_index finished_vertices[4];
} shellable_delta;

bool allowed_flip_1_to_5(solver *solver, quad_index q);
bool allowed_flip_5_to_1(solver *solver, quad_index q);
bool allowed_flip_2_to_4(solver *solver, quad_edge edge);
bool allowed_flip_4_to_2(solver *solver, quad_edge edge);
bool allowed_flip_3_line(solver *solver, quad_edge edge_a);
bool allowed_flip_3_cycle(solver *solver, quad_edge edge_a);

void flip_1_to_5(solver *solver, quad_index quad, shellable_delta *delta);
void flip_5_to_1(solver *solver, quad_index q, shellable_delta *delta);
void flip_2_to_4(solver *solver, quad_edge edge, shellable_delta *delta);
void flip_4_to_2(solver *solver, quad_edge edge, shellable_delta *delta);
void flip_3_line(solver *solver, quad_edge edge_a, shellable_delta *delta);
void flip_3_cycle(solver *solver, quad_edge edge_a, shellable_delta *delta);

bool allowed_finish_mesh(solver *solver, quad_index *boundary);
void finish_mesh(solver *solver, const quad_index *boundary);
void undo_finish_mesh(solver *solver, const quad_index *boundary);

void undo_shellable_delta(solver *solver, const shellable_delta *delta);

void shellable_dfs(solver *solver);

#endif
